package Network

import (
	"logs"
	"time"
	"token"

	"github.com/gorilla/websocket"
)

type ClientData struct {
	conn  *websocket.Conn
	token string
}

var wsClients = make(map[string]ClientData)
var lockk chan bool = make(chan bool, 1)

// 是否在线
func isOnline(clientID string) bool {
	lockk <- true
	_, isOnline := wsClients[clientID]
	<-lockk
	return isOnline
}

// --------------------------------------------- 连接管理部分

// 增加WebSocket连接
func addClient(clientID string, con *websocket.Conn) (canAdd bool) {

	if isOnline(clientID) {
		writeResponseToClient(clientID, &ServerResponse{
			Method:  "/wsLogin",
			Code:    noticeForceQuit,
			Message: mForceQuit,
			Result:  nil,
		})
		deleteClient(clientID)
		time.Sleep(time.Millisecond) // 如果不睡眠或者睡眠时间太短，两个连接都会被同时关掉
		logs.Print(clientID, mForceQuit)
		addConnection(clientID, con)
		return false
	}
	addConnection(clientID, con)
	return true
}

func addConnection(clientID string, con *websocket.Conn) {
	clientData := ClientData{
		conn:  con,
		token: "",
	}
	token.New(clientID, &clientData.token, func() { //此函数用于每次token变化后将token写回客户端
		//更新完client后才能writeResponse,注意死锁
		lockk <- true
		wsClients[clientID] = clientData
		<-lockk
		writeResponseToClient(clientID, &ServerResponse{
			Code:    Success,
			Method:  "/token",
			Message: "",
			Result:  map[string]string{"Token": clientData.token},
		})
	})
}

// 获取客户端连接
func getClient(clientID string) (clientConn *websocket.Conn, isOnline bool) {

	lockk <- true
	clientData, ok := wsClients[clientID]
	<-lockk
	return clientData.conn, ok
}

// 删除WebSocket连接
func deleteClient(clientID string) {

	lockk <- true
	clientData, ok := wsClients[clientID]
	<-lockk
	if !ok {
		return
	}
	lockk <- true
	clientData.conn.Close()
	token.Del(clientData.token)
	delete(wsClients, clientID)
	<-lockk
}

func onlineNum() int {
	lockk <- true
	defer func() {
		<-lockk
	}()
	return len(wsClients)
}
